package config

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"regexp"
	"unicode/utf8"

	"maki/utils"
)

var jsonData map[string]interface{}

func initJSON() {
	var configFile string
	if os.Getenv("SERVER_ENV") == ServerEnv.ProductionMode{
		configFile = "config.json"
	} else {
		configFile = "dev_config.json"
	}
	fmt.Println(configFile)
	bytes, err := ioutil.ReadFile(configFile)
	if err != nil {
		fmt.Println("ReadFile: ", err.Error())
		os.Exit(-1)
	}

	configStr := string(bytes[:])
	reg := regexp.MustCompile(`/\*.*\*/`)

	configStr = reg.ReplaceAllString(configStr, "")
	bytes = []byte(configStr)

	if err := json.Unmarshal(bytes, &jsonData); err != nil {
		fmt.Println("invalid config: ", err.Error())
		os.Exit(-1)
	}
}

type dBConfig struct {
	Dialect      string
	Database     string
	User         string
	Password     string
	Host         string
	Port         int
	Charset      string
	URL          string
	MaxIdleConns int
	MaxOpenConns int
}

// DBConfig 数据库相关配置
var DBConfig dBConfig

func initDB() {
	utils.SetStructByJSON(&DBConfig, jsonData["database"].(map[string]interface{}))
	if DBConfig.Dialect == "postgres" {
		DBConfig.URL = fmt.Sprintf("host=%s port=%d user=%s dbname=%s password=%s sslmode=disable",
			DBConfig.Host, DBConfig.Port, DBConfig.User, DBConfig.Database, DBConfig.Password)
	} else if DBConfig.Dialect == "mysql" {
		DBConfig.URL = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local",
			DBConfig.User, DBConfig.Password, DBConfig.Host, DBConfig.Port, DBConfig.Database, DBConfig.Charset)
	} else {
		panic("unsupported db")
	}
}

type redisConfig struct {
	Host      string
	Port      int
	Password  string
	URL       string
	MaxIdle   int
	MaxActive int
}

// RedisConfig redis相关配置
var RedisConfig redisConfig

func initRedis() {
	utils.SetStructByJSON(&RedisConfig, jsonData["redis"].(map[string]interface{}))
	url := fmt.Sprintf("%s:%d", RedisConfig.Host, RedisConfig.Port)
	RedisConfig.URL = url
}

type serverConfig struct {
	Host         string
	Env          string
	LogDir       string
	LogFile      string
	BodyLimit    string
	Port         int
	StatsEnabled bool
	StoreFolder  string
	TokenSecret  string
	TokenMaxAge  int
	PassSalt     string
	MailUser     string //域名邮箱账号
	MailPass     string //域名邮箱密码
	MailHost     string //smtp邮箱域名
	MailPort     int    //smtp邮箱端口
	MailFrom     string //邮件来源
}

// ServerConfig 服务器相关配置
var ServerConfig serverConfig

func initServer() {
	utils.SetStructByJSON(&ServerConfig, jsonData["server"].(map[string]interface{}))
	if !utils.FileExists(ServerConfig.StoreFolder) {
		os.MkdirAll(ServerConfig.StoreFolder, 0700)
	}
	if !utils.FileExists(ServerConfig.LogDir) {
		os.MkdirAll(ServerConfig.LogDir, 0700)
	}
	sep := string(os.PathSeparator)
	execPath, _ := os.Getwd()
	length := utf8.RuneCountInString(execPath)
	lastChar := execPath[length-1:]
	if lastChar != sep {
		execPath = execPath + sep
	}
	ymdStr := utils.GetTodayYMD("-")

	if ServerConfig.LogDir == "" {
		ServerConfig.LogDir = execPath
	} else {
		length := utf8.RuneCountInString(ServerConfig.LogDir)
		lastChar := ServerConfig.LogDir[length-1:]
		if lastChar != sep {
			ServerConfig.LogDir = ServerConfig.LogDir + sep
		}
	}
	ServerConfig.LogFile = ServerConfig.LogDir + ymdStr + ".log"

	env := os.Getenv("mode")
	if env != "" {
		ServerConfig.Env = env
	}
}

func init() {
	initConstants()
	initJSON()
	initDB()
	initServer()
}
